﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Reflection;

namespace jTCodeGenerate.Command
{
    public static class SQLineHelper
    {
        private static string _connStr
        {
            get
            {
                var path = Path.Combine(Directory.GetCurrentDirectory(), "lib\\SystemDB.db");
                var conStr = $"Data Source={path}";
                LogHelper.WriteLog($"DB：{path}");
                return conStr;
            }
        }
        public static DataTable SqlQuery(string sql)
        {
            DbCommand cmd = CreateCommand(sql, out DbConnection conn);
            DbDataReader reader = cmd.ExecuteReader();
            try
            {
                DataTable dt = new DataTable();
                dt.Load(reader);
                return dt;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                reader?.Close();
                conn?.Close();
            }
        }

        public static void ExecuteNonQuery(string sql)
        {
            DbCommand cmd = CreateCommand(sql, out DbConnection conn);
            try
            {
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                conn?.Close();
            }
        }

        private static DbCommand CreateCommand(string sql, out DbConnection dbConn)
        {
            try
            {
                SQLiteConnection conn = new SQLiteConnection(_connStr);
                dbConn = conn;
                conn.Open();
                DbCommand cmd = conn.CreateCommand();
                cmd.CommandText = sql;
                cmd.Connection = conn;
                return cmd;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static List<T> ToList<T>(this DataTable dt) where T : class
        {
            var colName = string.Empty;
            try
            {
                PropertyInfo[] propertyInfos = typeof(T).GetProperties();
                List<T> ts = new List<T>();
                foreach (DataRow row in dt.Rows)
                {
                    T t;
                    InitObj(out t);
                    foreach (PropertyInfo p in propertyInfos)
                    {
                        colName = p.Name;
                        if (dt.Columns.IndexOf(p.Name) != -1 && row[p.Name] != DBNull.Value)
                            p.SetValue(t, row[p.Name], null);
                    }
                    ts.Add(t);
                }
                return ts;
            }
            catch (Exception ex)
            {
                throw new Exception("字段名：" + colName + "，" + ex.Message);
            }
        }
        /// <summary>
        /// 通过无参构造函数创建对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        private static void InitObj<T>(out T t)
        {
            Type type = typeof(T);
            System.Reflection.ConstructorInfo[] constructorInfoArray = type.GetConstructors(System.Reflection.BindingFlags.Instance
            | System.Reflection.BindingFlags.NonPublic
            | System.Reflection.BindingFlags.Public);
            System.Reflection.ConstructorInfo noParameterConstructorInfo = null;
            foreach (System.Reflection.ConstructorInfo constructorInfo in constructorInfoArray)
            {
                System.Reflection.ParameterInfo[] parameterInfoArray = constructorInfo.GetParameters();
                if (0 == parameterInfoArray.Length)
                {
                    noParameterConstructorInfo = constructorInfo;
                    break;
                }
            }
            if (null == noParameterConstructorInfo)
            {
                throw new NotSupportedException("没有无参构造函数！");
            }
            t = (T)noParameterConstructorInfo.Invoke(null);
        }
    }
}
